package org.eiahe.hr.performance.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.ehe.business.drawing.domain.DesignDrawingSite;
import org.ehe.common.core.constant.RoleKeyConstants;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.core.utils.SpringUtils;
import org.ehe.common.satoken.utils.LoginHelper;
import org.ehe.system.domain.HrEmployee;
import org.ehe.system.domain.vo.SysPostVo;
import org.ehe.system.mapper.SysPostMapper;
import org.ehe.system.service.IHrEmployeeService;
import org.eiahe.hr.filler.EmployeeNameFiller;
import org.eiahe.hr.performance.domain.*;
import org.eiahe.hr.performance.domain.bo.PerformanceScoreBo;
import org.eiahe.hr.performance.domain.vo.PerformanceScoreVo;
import org.eiahe.hr.performance.event.PerformanceScoredEvent;
import org.eiahe.hr.performance.mapper.*;
import org.eiahe.hr.performance.service.IPerformancePositionIndicatorService;
import org.eiahe.hr.performance.service.IPerformanceScoreService;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 绩效评分Service业务层处理
 *
 * @author zhangnn
 */
@RequiredArgsConstructor
@Service
public class PerformanceScoreServiceImpl implements IPerformanceScoreService {

    private final PerformanceScoreMapper baseMapper;
    private final EmployeeNameFiller employeeNameFiller;
    private final IHrEmployeeService employeeService;
    private final PerformanceIndicatorMapper indicatorMapper;
    private final PerformanceCycleMapper cycleMapper;
    private final SysPostMapper postMapper;
    private final PerformanceScoreDetailMapper scoreDetailMapper;
    private final PerformanceResultMapper performanceResultMapper;
    private final PerformancePositionIndicatorMapper positionIndicatorMapper;
    private final IPerformancePositionIndicatorService positionIndicatorService;

    @Override
    public PerformanceScoreVo queryById(Long scoreId) {
        PerformanceScoreVo performanceScoreVo = baseMapper.selectVoById(scoreId);
        employeeNameFiller.fillEmployeeName(performanceScoreVo,
                PerformanceScoreVo::getEmployeeNo,
                PerformanceScoreVo::setEmployeeName);

        PerformanceIndicator indicator = indicatorMapper.selectById(performanceScoreVo.getIndicatorId());
        if (Objects.nonNull(indicator)) {
            performanceScoreVo.setIndicatorName(indicator.getIndicatorName());
        }
        PerformanceCycle cycle = cycleMapper.selectById(performanceScoreVo.getCycleId());
        if (Objects.nonNull(cycle)) {
            performanceScoreVo.setCycleName(cycle.getCycleName());
        }
        SysPostVo sysPostVo = postMapper.selectVoById(performanceScoreVo.getPositionId());
        if (Objects.nonNull(sysPostVo)) {
            performanceScoreVo.setPositionName(sysPostVo.getPostName());
        }
        return performanceScoreVo;
    }

    @Override
    public TableDataInfo<PerformanceScoreVo> queryPageListVo(PerformanceScoreBo score, PageQuery pageQuery) {
        LambdaQueryWrapper<PerformanceScore> lqw = buildQueryWrapper(score);
        Page<PerformanceScoreVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
        employeeNameFiller.fillEmployeeNames(page.getRecords(),
                PerformanceScoreVo::getEmployeeNo,
                PerformanceScoreVo::setEmployeeName);
        page.getRecords().forEach(p -> {
            PerformanceIndicator indicator = indicatorMapper.selectById(p.getIndicatorId());
            if (Objects.nonNull(indicator)) {
                p.setIndicatorName(indicator.getIndicatorName());
            }
            PerformanceCycle cycle = cycleMapper.selectById(p.getCycleId());
            if (Objects.nonNull(cycle)) {
                p.setCycleName(cycle.getCycleName());
            }
            SysPostVo sysPostVo = postMapper.selectVoById(p.getPositionId());
            if (Objects.nonNull(sysPostVo)) {
                p.setPositionName(sysPostVo.getPostName());
            }
            if (p.getEndTime().before(new Date())) {
                p.setStatus("2");
            }
            // 评分状态
            HrEmployee hrEmployee = employeeService.queryByUserId(LoginHelper.getUserId());
            if (Objects.nonNull(hrEmployee)) {
                PerformanceScoreDetail detail = scoreDetailMapper
                        .selectOne(new LambdaQueryWrapper<PerformanceScoreDetail>()
                                .eq(PerformanceScoreDetail::getScoreId, p.getScoreId())
                                .eq(PerformanceScoreDetail::getScorer, hrEmployee.getEmployeeNo()));
                if (Objects.nonNull(detail)) {
                    p.setOptScoreStatus("1");
                }
            }
        });
        return TableDataInfo.build(page);
    }

    private LambdaQueryWrapper<PerformanceScore> buildQueryWrapper(PerformanceScoreBo score) {
        LambdaQueryWrapper<PerformanceScore> lqw = Wrappers.lambdaQuery();
        // 如果不是管理员角色，则只能看到自己创建的点位
        if (!(StpUtil.hasRoleOr(RoleKeyConstants.HR_ROLES.toArray(new String[0])))) {
            // 获取当前登录用户名
            HrEmployee hrEmployee = employeeService.queryByUserId(LoginHelper.getUserId());
            if (Objects.nonNull(hrEmployee)) {
                // 添加创建者过滤条件
                lqw.like(PerformanceScore::getScorer, hrEmployee.getEmployeeNo());
            }
        }
        if (StringUtils.isNotBlank(score.getEmployeeName())) {
            List<String> employeeNos = employeeService.queryByEmployeeName(score.getEmployeeName());
            if (CollUtil.isEmpty(employeeNos)) {
                lqw.eq(PerformanceScore::getEmployeeNo, -1);
            } else {
                lqw.in(PerformanceScore::getEmployeeNo, employeeNos);
            }
        }
        lqw.eq(StringUtils.isNotBlank(score.getEmployeeNo()), PerformanceScore::getEmployeeNo, score.getEmployeeNo());
        lqw.eq(score.getIndicatorId() != null, PerformanceScore::getIndicatorId, score.getIndicatorId());
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(PerformanceScoreBo scoreBo) {
        scoreBo.setStatus("0"); // 未发布
        // 如果提供了评分人列表，则使用批量创建逻辑
        if (scoreBo.getScorers() != null && !scoreBo.getScorers().isEmpty()) {
            return insertBatchByBo(scoreBo);
        } else {
            // 否则按原来的逻辑单个创建
            PerformanceScore score = MapstructUtils.convert(scoreBo, PerformanceScore.class);
            boolean result = baseMapper.insert(score) > 0;

            // 更新对应的评分明细记录
            if (result) {
                // updateScoreDetail(score);
                //
                // // 发布评分事件，触发闭环处理
                // SpringUtils.context().publishEvent(
                // new PerformanceScoredEvent(this, scoreBo, score.getEmployeeNo(),
                // score.getIndicatorId()));
            }
            return result;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(PerformanceScoreBo scoreBo) {
        // 如果提供了评分人列表，则使用批量更新逻辑
        if (scoreBo.getScorers() != null && !scoreBo.getScorers().isEmpty()) {
            return updateBatchByBo(scoreBo);
        } else {
            // 否则按原来的逻辑单个更新
            PerformanceScore score = MapstructUtils.convert(scoreBo, PerformanceScore.class);

            boolean result = baseMapper.updateById(score) > 0;

            // 更新对应的评分明细记录
            if (result) {
                // updateScoreDetail(score);

                // 更新评分也重新计算结果
                // SpringUtils.context().publishEvent(
                // new PerformanceScoredEvent(this, scoreBo, score.getEmployeeNo(),
                // score.getIndicatorId()));
            }
            return result;
        }
    }

    /**
     * 发布
     * 
     * @param scoreId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean publish(Long scoreId) {
        // 否则按原来的逻辑单个更新
        PerformanceScore score = this.baseMapper.selectById(scoreId);
        score.setStatus("1"); // 已经发布
        boolean result = baseMapper.updateById(score) > 0;

        // 更新对应的评分明细记录
        if (result) {
            PerformanceScoreBo scoreBo = new PerformanceScoreBo();
            BeanUtils.copyProperties(score, scoreBo);
            // 更新评分也重新计算结果
            SpringUtils.context().publishEvent(
                    new PerformanceScoredEvent(this, scoreBo, score.getEmployeeNo(), score.getIndicatorId()));
        }
        return result;
    }

    /**
     * 批量更新评分记录
     *
     * @param scoreBo 评分BO
     * @return 是否成功
     */
    @Override
    public Boolean updateBatchByBo(PerformanceScoreBo scoreBo) {
        // 将评分人列表转换为逗号分隔的字符串
        String scorersStr = String.join(",", scoreBo.getScorers());
        scoreBo.setScorer(scorersStr);

        // 构建查询条件，使用scoreId进行精确匹配
        LambdaQueryWrapper<PerformanceScore> lqw = Wrappers.lambdaQuery();
        lqw.eq(PerformanceScore::getScoreId, scoreBo.getScoreId());
        lqw.eq(PerformanceScore::getDelFlag, "0");

        PerformanceScore score = MapstructUtils.convert(scoreBo, PerformanceScore.class);
        score.setScorer(scorersStr); // 确保评分人字段正确设置
        // 设置开始时间和结束时间
        score.setStartTime(scoreBo.getStartTime());
        score.setEndTime(scoreBo.getEndTime());

        boolean result = baseMapper.update(score, lqw) > 0;

        // 更新对应的评分明细记录
        if (result) {
            // updateScoreDetail(score);

            // 更新评分也重新计算结果
            SpringUtils.context().publishEvent(
                    new PerformanceScoredEvent(this, scoreBo, score.getEmployeeNo(), score.getIndicatorId()));
        }

        return result;
    }

    /**
     * 批量创建评分记录
     *
     * @param scoreBo 评分BO
     * @return 是否成功
     */
    @Override
    public Boolean insertBatchByBo(PerformanceScoreBo scoreBo) {
        // 将评分人列表转换为逗号分隔的字符串
        String scorersStr = String.join(",", scoreBo.getScorers());
        scoreBo.setScorer(scorersStr);

        // 创建评分记录，评分人字段存储所有评分人
        PerformanceScore score = MapstructUtils.convert(scoreBo, PerformanceScore.class);
        score.setScorer(scorersStr); // 确保评分人字段正确设置
        // 设置开始时间和结束时间
        score.setStartTime(scoreBo.getStartTime());
        score.setEndTime(scoreBo.getEndTime());

        boolean result = baseMapper.insert(score) > 0;

        return result;
    }

    /**
     * 更新评分明细记录
     *
     * @param score 评分记录
     */
    private void updateScoreDetail(PerformanceScore score) {
        // 获取结果ID
        Long resultId = getResultIdByEmployeeAndCycle(score.getEmployeeNo(), score.getCycleId());
        if (resultId == null) {
            return;
        }

        // 解析评分人列表
        List<String> scorers = new ArrayList<>();
        if (score.getScorer() != null && !score.getScorer().isEmpty()) {
            scorers = Arrays.asList(score.getScorer().split(","));
        }

        // 为每个评分人创建或更新评分明细记录
        for (String scorer : scorers) {
            // 查找是否已存在对应的评分明细记录
            LambdaQueryWrapper<PerformanceScoreDetail> lqw = Wrappers.lambdaQuery();
            lqw.eq(PerformanceScoreDetail::getResultId, resultId);
            lqw.eq(PerformanceScoreDetail::getIndicatorId, score.getIndicatorId());
            lqw.eq(PerformanceScoreDetail::getScorer, scorer);
            lqw.eq(PerformanceScoreDetail::getDelFlag, "0");

            PerformanceScoreDetail detail = scoreDetailMapper.selectOne(lqw);

            if (detail != null) {
                // 更新现有记录
                detail.setScore(score.getScore());
                detail.setScoreStatus("1"); // 已评分
                detail.setScoreId(score.getScoreId()); // 关联评分ID

                scoreDetailMapper.updateById(detail);
            } else {
                detail = new PerformanceScoreDetail();
                // 创建新记录
                detail.setScoreId(score.getScoreId());
                detail.setResultId(resultId);
                detail.setIndicatorId(score.getIndicatorId());
                detail.setScorer(scorer);
                detail.setScore(score.getScore());
                detail.setCreateBy(LoginHelper.getUserId());
                detail.setTenantId(LoginHelper.getTenantId());
                // 获取指标权重并计算加权得分
                BigDecimal weight = positionIndicatorService.getPositionIndicatorWeight(
                        score.getPositionId(), score.getIndicatorId());
                detail.setWeight(weight);

                // 计算加权得分
                BigDecimal weightedScore = positionIndicatorService.calculateWeightedScore(
                        score.getScore(), weight);
                detail.setWeightedScore(weightedScore);

                scoreDetailMapper.insert(detail);
            }
        }
    }

    /**
     * 根据员工工号和周期ID获取结果ID
     *
     * @param employeeNo 工号
     * @param cycleId    周期ID
     * @return 结果ID
     */
    private Long getResultIdByEmployeeAndCycle(String employeeNo, Long cycleId) {
        LambdaQueryWrapper<PerformanceResult> lqw = Wrappers.lambdaQuery();
        lqw.eq(PerformanceResult::getEmployeeNo, employeeNo);
        lqw.eq(PerformanceResult::getCycleId, cycleId);
        lqw.eq(PerformanceResult::getDelFlag, "0");

        PerformanceResult result = performanceResultMapper.selectOne(lqw);
        return result != null ? result.getResultId() : null;
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        if (isValid) {
            // 校验逻辑可以根据需要添加
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
